<!-- 修改表结构 -->
<template>
  <div class="main-wrapper">
    <el-form label-width="auto">
      <el-form-item label="表名">
        <el-row style="width: 100%">
          <el-col :span="21">
            <el-input v-model="props.tableName" disabled />
          </el-col>
          <el-col :span="2" :offset="1">
            <el-button
              style="display: inline-block; right: 14px; position: relative"
              @click="refreshTableInfo"
              >刷新</el-button
            >
          </el-col>
        </el-row>
      </el-form-item>
    </el-form>
    <div style="max-height: 400px; overflow: auto" v-loading="alterLoading">
      <!-- 列 -->
      <div class="column-wrapper" v-if="tableInfo && tableInfo.columnsInfo">
        <div style="margin-bottom: 6px">列</div>
        <el-row
          class="row-class"
          v-for="(item, index) in tableInfo.columnsInfo"
          :key="index"
        >
          <el-col :span="6">
            <el-select
              style="width: 100%"
              :disabled="!item.newColumn"
              v-model="item.type"
              placeholder="数据类型"
              :title="item.type"
              @change="updateRelevantData(index, true)"
            >
              <el-option
                v-for="item in columnDataTypeOption"
                :key="item.name"
                :label="item.name"
                :value="item.name"
              />
            </el-select>
          </el-col>
          <el-col :span="6" v-show="item.isLength">
            <el-input-number
              style="width: 100%"
              placeholder="长度"
              v-model="item.newLength"
              :min="item.length"
              :max="100000"
            >
            </el-input-number>
          </el-col>
          <el-col :span="item.isLength ? 8 : 14">
            <el-input
              style="width: 100%"
              v-model="item.newName"
              :disabled="tableType && !item.newColumn"
              placeholder="列名"
            />
          </el-col>
          <el-col :span="4">
            <div style="display: flex; justify-content: flex-end">
              <el-button
                :disabled="index == 0"
                @click="deleteColumnOrTag(index, item.newColumn, true)"
              >
                <el-icon>
                  <Minus v-if="item.newColumn" />
                  <Close v-else />
                </el-icon>
              </el-button>
              <el-button
                @click="clickConfirmButton(index, item.newColumn, true)"
              >
                <el-icon><Check /></el-icon>
              </el-button>
            </div>
          </el-col>
        </el-row>
        <el-row>
          <el-col :span="24">
            <el-button
              style="width: 100%"
              @click="addColumnOrTag(true)"
              :disabled="addedColumn"
            >
              <el-icon>
                <Plus />
              </el-icon>
            </el-button>
          </el-col>
        </el-row>
      </div>
      <!-- 标签 -->
      <div class="column-wrapper" v-if="props.tableType && tableInfo && tableInfo.tagsInfo">
        <div style="margin: 12px 0 6px 0">标签</div>
        <el-row
          class="row-class"
          v-for="(item, index) in tableInfo.tagsInfo"
          :key="index"
        >
          <el-col :span="6">
            <el-select
              style="width: 100%"
              :disabled="!item.newColumn"
              v-model="item.type"
              placeholder="数据类型"
              :title="item.type"
              @change="updateRelevantData(index, false)"
            >
              <el-option
                v-for="item in dataTypeOptions"
                :key="item.name"
                :label="item.name"
                :value="item.name"
              />
            </el-select>
          </el-col>
          <el-col :span="6" v-show="item.isLength">
            <el-input-number
              style="width: 100%"
              placeholder="长度"
              v-model="item.newLength"
              :min="item.length"
              :max="100000"
            >
            </el-input-number>
          </el-col>
          <el-col :span="item.isLength ? 8 : 14">
            <el-input
              style="width: 100%"
              v-model="item.newName"
              placeholder="标签名"
            />
          </el-col>
          <el-col :span="4">
            <div style="display: flex; justify-content: flex-end">
              <el-button
                :disabled="index == 0"
                @click="deleteColumnOrTag(index, item.newColumn, false)"
              >
                <el-icon>
                  <Minus v-if="item.newColumn" />
                  <Close v-else />
                </el-icon>
              </el-button>
              <el-button
                @click="clickConfirmButton(index, item.newColumn, false)"
              >
                <el-icon><Check /></el-icon>
              </el-button>
            </div>
          </el-col>
        </el-row>
        <el-row>
          <el-col :span="24">
            <el-button
              style="width: 100%"
              @click="addColumnOrTag(false)"
              :disabled="addedTag"
            >
              <el-icon>
                <Plus />
              </el-icon>
            </el-button>
          </el-col>
        </el-row>
      </div>
    </div>
  </div>
</template>
<script setup>
import { defineProps, onMounted, ref, watch, computed } from "vue";
import { getTableStructure, alterTable } from "../../api/index";
import { ElMessage, ElMessageBox } from "element-plus";
//TDEngine3.0 支持的数据类型
import { TDENGINE_DATA_TYPES } from "../../utils/global";
/**
 * 组件props
 */
const props = defineProps({
  tableName: {
    type: String,
    default: "",
    required: true,
  },
  tableType: {
    type: Boolean,
    // true 超级表 false 普通表
    default: false,
    required: true,
  },
  dbName: {
    type: String,
    default: "",
    required: true,
  },
  visiable: {
    type: Boolean,
    default: false,
    required: true,
  },
	dbInfo:{
		type:Object,
		default:{},
	},
	databaseInfo:{
		type:Array,
		default:[],
	}
});
/**
 * 变量区域
 */
const store = {
	info:props.dbInfo,
	databaseInfo: props.databaseInfo,
};
const tableInfo = ref(null);
//数据类型选项
const dataTypeOptions = ref(null);
//是否已经新增列
const addedColumn = ref(false);
//是否已经新增标签
const addedTag = ref(false);
//是否正在修改
const alterLoading = ref(false);
/**
 * 生命周期
 */
onMounted(() => {
  store.value = connectInfoStore();
  getTableStructureFunc();
  dataTypeOptions.value = JSON.parse(JSON.stringify(TDENGINE_DATA_TYPES));
});
/**
 * 属性监听
 */
watch(
  () => props.visiable,
  (newval) => {
    if (newval) {
      getTableStructureFunc();
    }
  }
);
/**
 * 计算属性
 */
const columnDataTypeOption = computed(() => {
  return JSON.parse(JSON.stringify(TDENGINE_DATA_TYPES)).filter(
    (item) => item.name != "JSON"
  );
});
/**
 * 方法区域
 */

const getTableStructureFunc = () => {
  let data = {
    dbConfig: {
      ...store.value.info,
      dbName: props.dbName,
    },
    tableDto: {
      name: props.tableName,
    },
  };
	alterLoading.value = true;
  getTableStructure(data)
    .then((res) => {
      if (res.code == 200 && res.data) {
        tableInfo.value = JSON.parse(JSON.stringify(res.data));
        initTableInfo(tableInfo);
      } else {
        ElMessage({
          type: "error",
          message: "获取表结构失败",
        });
      }
			alterLoading.value = false;
    })
    .catch((error) => {
      ElMessage({
        type: "error",
        message: "获取表结构失败："+error,
      });
			alterLoading.value = false;
    });
};
/**
 * 初始化后端返回的表格数据
 */
const initTableInfo = (tableInfo) => {
  tableInfo.value.columnsInfo.forEach((ele) => {
    ele.newLength = ele.length;
    ele.newName = ele.name;
    ele.newColumn = false;
  });
  tableInfo.value.tagsInfo.forEach((ele) => {
    ele.newLength = ele.length;
    ele.newName = ele.name;
    ele.newColumn = false;
  });
};
/**
 * 新增列
 */
const addColumnOrTag = (type) => {
  let column = {
    name: "",
    type: "INT",
    isLength: false,
    length: 8,
    newName: "",
    newLength: 8,
    newColumn: true,
  };
  if (type) {
    tableInfo.value.columnsInfo.push(column);
    // addedColumn.value = true;
  } else {
    tableInfo.value.tagsInfo.push(column);
    addedTag.value = true;
  }
};
/**
 * 类型修改，判断是否支持修改长度
 * @param index 索引
 * @param type 类型 true 列 false 标签
 */
const updateRelevantData = (index, type) => {
  let data = null;
  type
    ? (data = tableInfo.value.columnsInfo)
    : (data = tableInfo.value.tagsInfo);
  //要更新的列
  let target = data[index];
  let dataType = dataTypeOptions.value.find((item) => item.name == target.type);
  target.isLength = dataType.isLength;
};
/**
 * 删除列或者标签
 * @param index 索引
 * @param newColumn 是否是新增的字段或标签
 * @param type true 列 false 标签
 */
const deleteColumnOrTag = (index, newColumn, type) => {
  if (newColumn) {
    alterLoading.value = true;
    if (type) {
      //删除新增的列
      tableInfo.value.columnsInfo.splice(index, 1);
      addedColumn.value = false;
    } else {
      //删除新增的标签
      tableInfo.value.tagsInfo.splice(index, 1);
      addedTag.value = false;
    }
    alterLoading.value = false;
  } else {
    //删除数据库中的列
    ElMessageBox.confirm("确认要删除?", "提示", {
      confirmButtonText: "确认",
      cancelButtonText: "取消",
      type: "warning",
    })
      .then(() => {
        alterLoading.value = true;
        //删除字段，删除标签
        type ? alterFunc(2, index) : alterFunc(6, index);
      })
      .catch((e) => {
        if (e === "cancel") {
          ElMessage({
            type: "info",
            message: "取消删除",
          });
        } else {
          alterLoading.value = true;
          ElMessage({
            type: "error",
            message: "删除失败:" + error,
          });
        }
      });
  }
};
/**
 * 点击确认提交按钮
 * @param index 索引
 * @param newColumn 是否为新增的列
 * @param type true 字段 false 标签
 */
const clickConfirmButton = (index, newColumn, type) => {
  if (newColumn) {
    // 新增字段 新增标签
    alterLoading.value = true;
    type ? alterFunc(1, index) : alterFunc(5, index);
  } else {
    //普通表 标签修改名称或者修改长度
    let columnInfo = type
      ? tableInfo.value.columnsInfo[index]
      : tableInfo.value.tagsInfo[index];
    let nameFlag = false;
    let lengthFlag = false;
    if (columnInfo.name != columnInfo.newName) {
      nameFlag = true;
    }
    if (columnInfo.isLength && columnInfo.length != columnInfo.newLength) {
      lengthFlag = true;
    }
    if (lengthFlag && nameFlag) {
      ElMessage({
        type: "warning",
        message: "标签名称和长度不能同时修改!",
      });
    } else if (lengthFlag) {
      alterLoading.value = true;
      type ? alterFunc(3, index) : alterFunc(7, index);
    } else if (nameFlag) {
      alterLoading.value = true;
      type ? alterFunc(4, index) : alterFunc(8, index);
    }
  }
};
/**
 * 修改表的所有操作
 * 包括普通表和超表，只需要提供参数
 * @param type 需要进行何种修改
 * 1 新增字段
 * 2 删除字段
 * 3 修改字段长度
 * 4 修改字段名称 只允许普通表修改
 * 5 新增标签
 * 6 删除标签
 * 7 修改标签长度
 * 8 重命名标签
 * @param index 需要修改的索引
 */
const alterFunc = (type, index) => {
  let columnInfo = null;
  //不难看出 操作类型大于4 都是标签
  let columnOrTag = type > 4 ? "TAG" : "COLUMN";
  if (columnOrTag == "COLUMN") {
    columnInfo = tableInfo.value.columnsInfo[index];
  } else {
    columnInfo = tableInfo.value.tagsInfo[index];
  }
  let data = {
    dbConfig: {
      ...store.value.info,
      dbName: props.dbName,
    },
    tableName: props.tableName,
    fieldType: columnOrTag,
    tableType: props.tableType ? "STABLE" : "TABLE",
    operation: type,
    columnInfo,
  };
  alterTable(data)
    .then((res) => {
      if (res.code == 200 && res.data) {
        tableInfo.value = res.data;
        initTableInfo(tableInfo);
        ElMessage({
          type: "success",
          message: "修改表格成功",
        });
        if (type == 1) {
          addedColumn.value = false;
        } else if (type == 5) {
          addedTag.value = false;
        }
      } else {
        ElMessage({
          type: "error",
          message: "修改表格错误：" + res.msg,
        });
      }
      alterLoading.value = false;
    })
    .catch((error) => {
      ElMessage({
        type: "error",
        message: "修改表格错误：" + error,
      });
      alterLoading.value = false;
    });
};

const getNameInputSpan = (columnInfo) => {
  return columnInfo.newColumn
    ? columnInfo.isLength
      ? 8
      : 14
    : columnInfo.isLength
    ? 10
    : 16;
};

const refreshTableInfo = ()=>{
	tableInfo.value.columnsInfo.forEach(item=>{
		if(!item.newColumn){
			item.newName = item.name;
			item.newLength = item.length;
		}
	})
	tableInfo.value.tagsInfo.forEach(item=>{
		if(!item.newColumn){
			item.newName = item.name;
			item.newLength = item.length;
		}
	})
}
</script>
<style lang="less" scoped>
.main-wrapper {
  max-height: 500px;
  width: 100%;
  .column-wrapper {
    .row-class:not(:last-child) {
      margin-bottom: 12px;
    }
  }
}
</style>
